package com.ming.common.liteflow.core.config;


import com.alibaba.fastjson2.JSON;
import com.yomahub.liteflow.property.LiteflowConfig;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class IvyConfigUtil {

    public static LiteflowConfig getDefaultConfig(){
        return getDefaultConfig(null);
    }

    public static LiteflowConfig getDefaultConfig(IvyConfig conf){
        LiteflowConfig config = new LiteflowConfig();
        Map<String,String> extMap = new HashMap<>();
        extMap.put("url","jdbc:mysql://127.0.0.1:3306/ivy");
        extMap.put("driverClassName","com.mysql.cj.jdbc.Driver");
        extMap.put("username","root");
        extMap.put("password","123456");
        extMap.put("applicationName","demo");
        extMap.put("sqlLogEnabled","true");//是否开启SQL日志
        extMap.put("pollingEnabled","true");//是否开启SQL数据轮询自动刷新机制 默认不开启
        extMap.put("pollingIntervalSeconds","60");
        extMap.put("pollingStartSeconds","60");

        extMap.put("chainTableName","ivy_lf_el_table");
        extMap.put("chainApplicationNameField","application_name");
        extMap.put("chainNameField","chain_name");
        extMap.put("elDataField","el_data");
        extMap.put("chainEnableField","enable");

        extMap.put("scriptTableName","ivy_lf_script_node_table");
        extMap.put("scriptApplicationNameField","application_name");
        extMap.put("scriptIdField","script_node_id");
        extMap.put("scriptNameField","script_node_name");
        extMap.put("scriptDataField","script_node_data");
        extMap.put("scriptTypeField","script_node_type");
        extMap.put("scriptLanguageField","script_language");
        extMap.put("scriptEnableField","enable");
        config.setRuleSourceExtDataMap(extMap);

        if(conf == null){
            //-----------------以下非必须-----------------
            //liteflow是否开启，默认为true
            config.setEnable(true);
            //liteflow的banner打印是否开启，默认为true
            config.setPrintBanner(true);
            //上下文的最大数量槽，默认值为1024
            config.setSlotSize(1024);
            //FlowExecutor的execute2Future的线程数，默认为64
            config.setMainExecutorWorks(64);
            //FlowExecutor的execute2Future的自定义线程池Builder，LiteFlow提供了默认的Builder
            config.setMainExecutorClass("com.yomahub.liteflow.thread.LiteFlowDefaultMainExecutorBuilder");
            //自定义请求ID的生成类，LiteFlow提供了默认的生成类
            config.setRequestIdGeneratorClass("com.yomahub.liteflow.flow.id.DefaultRequestIdGenerator");
            //并行节点的线程池Builder，LiteFlow提供了默认的Builder
            config.setThreadExecutorClass("com.yomahub.liteflow.thread.LiteFlowDefaultWhenExecutorBuilder");
            //异步线程最长的等待时间(只用于when)，默认值为15000
            config.setWhenMaxWaitTime(15000);
            //异步线程最长的等待时间(只用于when)，默认值为MILLISECONDS，毫秒
            config.setWhenMaxWaitTimeUnit(TimeUnit.MILLISECONDS);
            //when节点全局异步线程池最大线程数，默认为16
            config.setWhenMaxWorkers(16);
            //when节点全局异步线程池等待队列数，默认为512
            config.setWhenQueueLimit(512);
            //并行循环子项线程池最大线程数，默认为16
            config.setParallelMaxWorkers(16);
            //并行循环子项线程池等待队列数，默认为512
            config.setParallelQueueLimit(512);
            //并行循环子项的线程池Builder，LiteFlow提供了默认的Builder
            config.setParallelLoopExecutorClass("com.yomahub.liteflow.test.customThreadPool.CustomThreadBuilder");
            //是否在启动的时候就解析规则，默认为true
            config.setParseOnStart(true);
            //全局重试次数，默认为0
            config.setRetryCount(0);
            //是否支持不同类型的加载方式混用，默认为false
            config.setSupportMultipleType(false);
            //全局默认节点执行器
            config.setNodeExecutorClass("com.yomahub.liteflow.flow.executor.DefaultNodeExecutor");
            //是否打印执行中过程中的日志，默认为true
            config.setPrintExecutionLog(true);
            //是否开启本地文件监听，默认为false
            config.setEnableMonitorFile(false);
            //是否开启快速解析模式，默认为false
            config.setFastLoad(false);
            //简易监控配置选项
            //监控是否开启，默认不开启
            config.setEnableLog(false);
            //监控队列存储大小，默认值为200
            config.setQueueLimit(200);
            //监控一开始延迟多少执行，默认值为300000毫秒，也就是5分钟
            config.setDelay(300000L);
            //监控日志打印每过多少时间执行一次，默认值为300000毫秒，也就是5分钟
            config.setPeriod(300000L);
        }else{
            //-----------------以下非必须-----------------
            //liteflow是否开启，默认为true
            config.setEnable(conf.getEnable());
            //liteflow的banner打印是否开启，默认为true
            config.setPrintBanner(conf.getPrintBanner());
            //上下文的最大数量槽，默认值为1024
            config.setSlotSize(conf.getSlotSize());
            //FlowExecutor的execute2Future的线程数，默认为64
            config.setMainExecutorWorks(conf.getMainExecutorWorks());
            //FlowExecutor的execute2Future的自定义线程池Builder，LiteFlow提供了默认的Builder
            config.setMainExecutorClass(conf.getMainExecutorClass());
            //自定义请求ID的生成类，LiteFlow提供了默认的生成类
            config.setRequestIdGeneratorClass(conf.getRequestIdGeneratorClass());
            //并行节点的线程池Builder，LiteFlow提供了默认的Builder
            config.setThreadExecutorClass(conf.getThreadExecutorClass());
            //异步线程最长的等待时间(只用于when)，默认值为15000
            config.setWhenMaxWaitTime(conf.getWhenMaxWaitTime());
            //异步线程最长的等待时间(只用于when)，默认值为MILLISECONDS，毫秒
            switch (conf.getWhenMaxWaitTimeUnit()){
                case "DAYS": config.setWhenMaxWaitTimeUnit(TimeUnit.DAYS);break;
                case "HOURS": config.setWhenMaxWaitTimeUnit(TimeUnit.HOURS);break;
                case "MINUTES": config.setWhenMaxWaitTimeUnit(TimeUnit.MINUTES);break;
                case "SECONDS": config.setWhenMaxWaitTimeUnit(TimeUnit.SECONDS);break;
                case "MILLISECONDS": config.setWhenMaxWaitTimeUnit(TimeUnit.MILLISECONDS);break;
                case "MICROSECONDS": config.setWhenMaxWaitTimeUnit(TimeUnit.MICROSECONDS);break;
                case "NANOSECONDS": config.setWhenMaxWaitTimeUnit(TimeUnit.NANOSECONDS);break;
                default: config.setWhenMaxWaitTimeUnit(TimeUnit.MILLISECONDS);break;
            }
            //when节点全局异步线程池最大线程数，默认为16
            config.setWhenMaxWorkers(conf.getWhenMaxWorkers());
            //开启WHEN线程池隔离
            config.setWhenThreadPoolIsolate(conf.getWhenThreadPoolIsolate());
            //when节点全局异步线程池等待队列数，默认为512
            config.setWhenQueueLimit(conf.getWhenQueueLimit());
            //并行循环子项线程池最大线程数，默认为16
            config.setParallelMaxWorkers(conf.getParallelLoopMaxWorkers());
            //并行循环子项线程池等待队列数，默认为512
            config.setParallelQueueLimit(conf.getParallelLoopQueueLimit());
            //并行循环子项的线程池Builder，LiteFlow提供了默认的Builder
            config.setParallelLoopExecutorClass(conf.getParallelLoopExecutorClass());
            //是否在启动的时候就解析规则，默认为true
            config.setParseOnStart(conf.getParseOnStart());
            //全局重试次数，默认为0
            config.setRetryCount(conf.getRetryCount());
            //是否支持不同类型的加载方式混用，默认为false
            config.setSupportMultipleType(conf.getSupportMultipleType());
            //全局默认节点执行器
            config.setNodeExecutorClass(conf.getNodeExecutorClass());
            //是否打印执行中过程中的日志，默认为true
            config.setPrintExecutionLog(conf.getPrintExecutionLog());
            //是否开启本地文件监听，默认为false
            config.setEnableMonitorFile(conf.getEnableMonitorFile());
            //是否开启快速解析模式，默认为false
            config.setFastLoad(conf.getFastLoad());
            //简易监控配置选项
            //监控是否开启，默认不开启
            config.setEnableLog(conf.getEnableLog());
            //监控队列存储大小，默认值为200
            config.setQueueLimit(conf.getQueueLimit());
            //监控一开始延迟多少执行，默认值为300000毫秒，也就是5分钟
            config.setDelay(conf.getDelay());
            //监控日志打印每过多少时间执行一次，默认值为300000毫秒，也就是5分钟
            config.setPeriod(conf.getPeriod());
        }
        return config;
    }


    public static LiteflowConfig getConfig(IvyConfig conf){
        LiteflowConfig config = getDefaultConfig(conf);
        switch (conf.getRuleType()){
            case "ruleSource":
            case "ruleSourceCustom":
                config.setRuleSource(conf.getRuleSource());
                break;
            default:
                switch (conf.getConfigType()){
                    case 1:
                        String extData = conf.getRuleSourceExtDataMap();
                        Map<String,String> map = JSON.parseObject(extData, Map.class);
                        config.setRuleSourceExtDataMap(map);
                        break;
                    case 2:
                        config.setRuleSourceExtData(conf.getRuleSourceExtData());
                        break;
                }
        }
        return config;
    }
}
